//
//  Parser.swift
//  PrattParser
//
//  Created by 神经骚栋 on 2023/9/5.
//

import Cocoa


class Parser: NSObject {
    
    var lexer: Lexer?
    
    var cur: Token?
    
    var peek: Token?

    
    var infixParseFnHashMap: [TokenType : String] = [:]
    var prefixParseFnHashMap: [TokenType : String] = [:]

    
    init(_ lexer: Lexer) {
        super.init()
        self.lexer = lexer;
        prefixParseFnHashMap.updateValue("parseInteger", forKey: TokenType.NUM)
        prefixParseFnHashMap.updateValue("parsePrefixExpression", forKey: TokenType.MINUS)
        prefixParseFnHashMap.updateValue("parseGroupExpression", forKey: TokenType.LPAREN)
        
        infixParseFnHashMap.updateValue("parseInfixExpression", forKey: TokenType.PLUS)
        infixParseFnHashMap.updateValue("parseInfixExpression", forKey: TokenType.MINUS)
        infixParseFnHashMap.updateValue("parseInfixExpression", forKey: TokenType.ASTERISK)
        infixParseFnHashMap.updateValue("parseInfixExpression", forKey: TokenType.SLASH)
        infixParseFnHashMap.updateValue("parseInfixExpression", forKey: TokenType.HAT)
        
        nextToken();
        nextToken();
    }
    
    func nextToken() {
        cur = peek;
        do {
            try peek = lexer?.nextToken();
        } catch {
            print("发生 Lexer 错误")
        }
    }
    
    func curTokenIs(_ type: TokenType) -> Bool {
        return cur?.type == type
    }
    
    func peekTokenIs(_ type: TokenType) -> Bool {
        return peek?.type == type
    }
    
    public func peekPrecedence() -> Precedence? {
        return Precedence.getPrecedence(peek?.type);
    }
    
    // 构建AST树主入口
    public func parseMain() -> Expression? {
        return parseExpression(Precedence.LOWEST);
    }
    
    // 构建AST语法结构树的主要函数
    func parseExpression(_ precedence: Precedence) -> Expression? {
        let funcName: String?  = prefixParseFnHashMap[cur?.type ?? TokenType.None];
        if (funcName == nil) {
            print("未找到AST节点构建函数名称")
            return nil
        }
        // 获取左节点
        var leftExpression: Expression? = getPrefixExpression(funcName);
        
        while (!peekTokenIs(TokenType.EOF) && precedence.rawValue < peekPrecedence()?.rawValue ?? 0) {
            let infixParseFnName: String?  = infixParseFnHashMap[peek?.type ?? TokenType.None];
            if (infixParseFnName == nil) {
                print("未找到AST节点构建函数名称")
                return leftExpression;
            }
            nextToken();
            leftExpression = parseInfixExpression(leftExpression);
        }
        return leftExpression
    }
    
    // 各个语法节点的构造函数
    func getPrefixExpression(_ funcName: String?) -> Expression? {
        switch(funcName) {
        case "parseInteger" :
            return parseInteger()
        case "parsePrefixExpression":
            return parsePrefixExpression()
        case "parseGroupExpression":
            return parseGroupExpression()
        default:
            return nil
        }
    }
    
    // 中置节点
    func parseInfixExpression(_ left: Expression?) -> Expression? {
        let infixExpression = InfixExpression();
        infixExpression.left = left;
        infixExpression.operatorValue = cur?.value;
        let precedence: Precedence = Precedence.getPrecedence(cur?.type);
        nextToken();
        infixExpression.right = parseExpression(precedence);
        return infixExpression
    }
    
    func parsePrefixExpression() -> Expression? {
        let prefixExpression = PrefixExpression();
        prefixExpression.operatorValue = cur?.value;
        nextToken();
        prefixExpression.right = parseExpression(Precedence.PREFIX);
        return prefixExpression;
    }
    
    func parseInteger() -> Expression? {
        let number = Double(cur?.value ?? "0")
        let integerExpression = IntegerExpression(value: number)
        return integerExpression
    }
    
    func parseGroupExpression() -> Expression? {
        nextToken();
        let exp = parseExpression(Precedence.LOWEST)
        nextToken();
        return exp
    }
}
